package values.item.building
{
import framework.dao.EntryUtil;

import mapengine.building.FactoryMapBuilding;

import utils.TimeUtil;

import values.common.BonusValue;
import values.common.CostValue;
import values.events.BuildingItemValueEvent;
import values.item.BuildingItemValue;
import values.item.IItemValue;
import values.item.ItemUpgradeValue;
import values.product.ProductValue;

[Event(name="startProduce", type="values.events.BuildingItemValueEvent")]
[Event(name="collectProduct", type="values.events.BuildingItemValueEvent")]
/**
 * FactoryBuildingItemValue
 * @author jliang
 *
 */
public class FactoryBuildingItemValue extends BuildingItemValue
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function FactoryBuildingItemValue()
	{
		super();
	}
	//==========================================================================
	//  Properties
	//==========================================================================
	/**
	 * 生产项目
	 * @return 
	 * 
	 */	
	protected var _currentProduct:ProductValue;
	
	protected function setCurrentProduct(key:String):void
	{
		speicalParams.product = key;
		
		for each (var pvo:ProductValue in productList)
		{
			if (pvo.key == key) _currentProduct = pvo;
		}
	}
	
	public function get currentProduct():ProductValue
	{
		return _currentProduct;
	}
	
	/**
	 * 收获消耗 
	 * @return 
	 * 
	 */	
	public function get collectCost():CostValue
	{
		return EntryUtil.mapping(template.params.collect_cost, CostValue);
	}
	
	/**
	 * 开始生产的时间戳, 单位是: 秒
	 * @return 
	 * 
	 */			
	protected function setStartProduceTime(value:Number):void
	{
		speicalParams.start_time = value;
	}
	
	public function get startProduceTime():Number
	{
		return speicalParams.start_time;
	}
	
	/**
	 * 剩余的生产时间, 单位是: 秒
	 * @return 
	 * 
	 */	
	public function get produceTimeRest():Number
	{
		return currentProduct.time - (TimeUtil.currentGameTimeSec - startProduceTime);
	}
	
	/**
	 * 是否已经完成生产 
	 * @return 
	 * 
	 */	
	public function get isProduceComplete():Boolean
	{
		return state == 3;
	}
	
	/**
	 * 是否正在生产
	 * @return 
	 * 
	 */	
	public function get isProducing():Boolean
	{
		return state == 2;
	}
	
	/**
	 * 是否已经在等待生产 
	 * @return 
	 * 
	 */	
	public function get isWaitingProduce():Boolean
	{
		return state == 1;
	}
	
	protected var _productList:Vector.<ProductValue>;

	public function get productList():Vector.<ProductValue>
	{
		if (!_productList)
		{
			_productList = new Vector.<ProductValue>();
			
			for (var i:int = 0; i < factoryBuildingTemplate.productList.length; i++)
			{
				var pvo:ProductValue = new ProductValue();
				pvo.template = factoryBuildingTemplate.productList[i];
				pvo.bonusFunc = bonusPlusFunc;
				pvo.owner = this;
				productList.push(pvo);
			}
		}
		return _productList;
	}
	
	public function get factoryBuildingTemplate():FactoryBuildingItemTemplateValue
	{
		return FactoryBuildingItemTemplateValue(template);
	}
	
	public function getProductByKey(key:String):ProductValue
	{
		for each (var p:ProductValue in productList)
		{
			if (p.key == key) return p;
		}
		return null;
	}
	//==========================================================================
	//  Overridden methods: ItemValue
	//==========================================================================		
	override public function get mapObjectClassRef():Class
	{
		return FactoryMapBuilding;
	}
	
	override public function initialize(params:*):void
	{
		super.initialize(params);
		
		if (!speicalParams.hasOwnProperty("start_time"))
		{
			setStartProduceTime(0);
		}
		
		if (speicalParams.hasOwnProperty("product"))
		{
			setCurrentProduct(speicalParams.product);
		}
	}
	//==========================================================================
	//  Public methods
	//==========================================================================	
	public function startProduce(productKey:String, time:Number = 0):CostValue
	{			
		setCurrentProduct(productKey);
		if (time > 0) 
		{
			setStartProduceTime(time);	
			
			var cost:CostValue = getProductByKey(productKey).cost;
			
			var evt:BuildingItemValueEvent = new BuildingItemValueEvent(BuildingItemValueEvent.START_PRODUCE);
			evt.params = { item:this, product:productKey, time:startProduceTime, cost:cost };
			this.dispatchEvent(evt);
            return cost;
		}		
        return null;
	}
	
	public function collectProduct():Object
	{
		var bonus:BonusValue = currentProduct.bonus;
		
		var itemBonus:Vector.<IItemValue> = bonus.bonus;
		
		var plus:Number = 1;
		
		if (bonus.params.hasOwnProperty("possiblePlus") && bonus.params.possiblePlus > 1)
		{
			plus = bonus.params.possiblePlus;
		}
		
		var evt:BuildingItemValueEvent = new BuildingItemValueEvent(BuildingItemValueEvent.COLLECT_PRODUCT);
		evt.params = { item:this, bonus:itemBonus, plus:plus, cost:collectCost };
		this.dispatchEvent(evt);
		
		return { bonus:itemBonus, plus:plus, cost:collectCost };
	}
	
	public function resetProduceSetting():void
	{
		setStartProduceTime(0);
		
		delete speicalParams["product"];
		
		_currentProduct = null;
	}
	
	public function checkProductActive(productKey:String):Boolean
	{
		for (var i:int = 1; i <= level; i++)
		{
			var uvo:ItemUpgradeValue = buildingTemplate.getUpgradeByLevel(i);
			if (String(uvo.effect.product).indexOf(productKey) >= 0)
			{
				return true;
			}
		}
		return false;
	}
	//==========================================================================
	//  Protected methods
	//==========================================================================
	protected function bonusPlusFunc(pvo:ProductValue):BonusValue
	{
		var plus:Number = factoryBuildingTemplate.getBonusPlusByLevel(level);
		var bonus:BonusValue = pvo.template.bonus.clone();
		
		var bonusPlus:Number = pvo.possiblePlus;
		for each (var obj:* in bonus.xmlData)
		{
			var temp:Number = (1 + plus) * Number(obj.@num);
			if (int(obj.@index) == 1)
			{
				temp = bonusPlus * temp;
			}
			obj.@num = Math.ceil(temp);
		}
		bonus.params.possiblePlus = bonusPlus;
		return bonus;
	}
}
}



